package backend

import (
	"bufio"
	"fmt"
	"io"
	"log"
	"net"
	"os"
	"path/filepath"
	"strconv"
	"strings"
	"sync"
	"time"
)

// WITSReceiver WITS-A数据接收服务
type WITSReceiver struct {
	host        string
	port        int
	listener    net.Listener
	clients     map[string]*WITSClient
	mutex       sync.RWMutex
	running     bool
	dataDir     string
	currentFile *os.File
	currentDate string
	fileMutex   sync.Mutex
	dataHandler func(data []byte, clientAddr string) // 数据处理回调函数
	logger      *Logger                              // 自定义日志器
}

// WITSClient WITS客户端连接
type WITSClient struct {
	conn     net.Conn
	address  string
	buffer   []byte
	receiver *WITSReceiver
}

// NewWITSReceiver 创建WITS-A接收服务
func NewWITSReceiver(host string, port int, dataDir string) *WITSReceiver {
	return &WITSReceiver{
		host:    host,
		port:    port,
		clients: make(map[string]*WITSClient),
		dataDir: dataDir,
	}
}

// SetLogger 设置自定义日志器
func (r *WITSReceiver) SetLogger(logger *Logger) {
	r.logger = logger
}

// SetDataHandler 设置数据处理回调函数
func (r *WITSReceiver) SetDataHandler(handler func(data []byte, clientAddr string)) {
	r.dataHandler = handler
}

// Start 启动WITS-A接收服务
func (r *WITSReceiver) Start() error {
	addr := fmt.Sprintf("%s:%d", r.host, r.port)
	listener, err := net.Listen("tcp", addr)
	if err != nil {
		return fmt.Errorf("failed to start WITS receiver: %v", err)
	}

	r.listener = listener
	r.running = true

	if r.logger != nil {
		r.logger.Info("WITS-A receiver service started on %s", addr)
	} else {
		log.Printf("WITS-A接收服务启动在 %s", addr)
	}

	// 确保数据目录存在
	if err := os.MkdirAll(r.dataDir, 0755); err != nil {
		if r.logger != nil {
			r.logger.Error("Failed to create data directory: %v", err)
		}
		return fmt.Errorf("failed to create data directory: %v", err)
	}

	// 启动文件管理协程
	go r.fileManager()

	// 接受连接
	go r.acceptConnections()

	return nil
}

// Stop 停止WITS-A接收服务
func (r *WITSReceiver) Stop() error {
	r.running = false

	if r.logger != nil {
		r.logger.Info("Stopping WITS-A receiver service")
	}

	if r.listener != nil {
		r.listener.Close()
	}

	// 关闭所有客户端连接
	r.mutex.Lock()
	for _, client := range r.clients {
		client.conn.Close()
	}
	r.clients = make(map[string]*WITSClient)
	r.mutex.Unlock()

	// 关闭当前文件
	r.fileMutex.Lock()
	if r.currentFile != nil {
		r.currentFile.Close()
		r.currentFile = nil
	}
	r.fileMutex.Unlock()

	if r.logger != nil {
		r.logger.Info("WITS-A receiver service stopped")
	} else {
		log.Println("WITS-A接收服务已停止")
	}
	return nil
}

// acceptConnections 接受客户端连接
func (r *WITSReceiver) acceptConnections() {
	defer func() {
		if rec := recover(); rec != nil {
			if r.logger != nil {
				r.logger.Error("Panic recovered in acceptConnections: %v", rec)
			} else {
				log.Printf("捕获到panic在acceptConnections中，错误: %v", rec)
			}
		}
	}()

	for r.running {
		conn, err := r.listener.Accept()
		if err != nil {
			if r.running {
				if r.logger != nil {
					r.logger.Error("Failed to accept connection: %v", err)
				} else {
					log.Printf("接受连接失败: %v", err)
				}
			}
			continue
		}

		// 在客户端处理逻辑外添加panic保护
		func() {
			defer func() {
				if rec := recover(); rec != nil {
					if r.logger != nil {
						r.logger.Error("Panic recovered while accepting connection from %s: %v", conn.RemoteAddr().String(), rec)
					} else {
						log.Printf("捕获到panic在接收连接时，客户端: %s, 错误: %v", conn.RemoteAddr().String(), rec)
					}
					// 确保连接被关闭
					conn.Close()
				}
			}()

			client := &WITSClient{
				conn:     conn,
				address:  conn.RemoteAddr().String(),
				buffer:   make([]byte, 0, 4096),
				receiver: r,
			}

			// 添加到客户端列表
			r.mutex.Lock()
			r.clients[client.address] = client
			r.mutex.Unlock()

			if r.logger != nil {
				r.logger.Info("New WITS client connected: %s", client.address)
			} else {
				log.Printf("新的WITS客户端连接: %s", client.address)
			}

			// 启动处理协程
			go r.handleClient(client)
		}()
	}
}

// handleClient 处理客户端数据
func (r *WITSReceiver) handleClient(client *WITSClient) {
	defer func() {
		if rec := recover(); rec != nil {
			// 捕获panic，记录错误但不终止服务
			if r.logger != nil {
				r.logger.Error("Panic recovered in handleClient for %s: %v", client.address, rec)
			} else {
				log.Printf("捕获到panic在handleClient中，客户端: %s, 错误: %v", client.address, rec)
			}
		}

		// 在客户端断开连接前，保存缓冲区中剩余的原始数据
		if len(client.buffer) > 0 {
			if r.logger != nil {
				r.logger.Info("Saving remaining buffer data (%d bytes) from disconnected client %s", len(client.buffer), client.address)
			} else {
				log.Printf("保存断开连接的客户端 %s 的剩余缓冲区数据 (%d bytes)", client.address, len(client.buffer))
			}
			if err := r.saveBinaryData(client.buffer); err != nil {
				if r.logger != nil {
					r.logger.Error("Failed to save remaining buffer data from %s: %v", client.address, err)
				} else {
					log.Printf("保存剩余缓冲区数据失败 %s: %v", client.address, err)
				}
			}
		}

		client.conn.Close()
		r.mutex.Lock()
		delete(r.clients, client.address)
		r.mutex.Unlock()
		if r.logger != nil {
			r.logger.Info("WITS client disconnected: %s", client.address)
		} else {
			log.Printf("WITS客户端断开连接: %s", client.address)
		}
	}()

	reader := bufio.NewReader(client.conn)

	for r.running {
		// 读取数据
		data := make([]byte, 1024)
		n, err := reader.Read(data)
		if err != nil {
			if err != io.EOF {
				if r.logger != nil {
					r.logger.Error("Failed to read client data from %s: %v", client.address, err)
				} else {
					log.Printf("读取客户端数据失败 %s: %v", client.address, err)
				}
			}
			break
		}

		if n > 0 {
			// 在数据处理前添加panic保护
			func() {
				defer func() {
					if rec := recover(); rec != nil {
						if r.logger != nil {
							r.logger.Error("Panic recovered while processing data from %s: %v", client.address, rec)
						} else {
							log.Printf("捕获到panic在处理数据时，客户端: %s, 错误: %v", client.address, rec)
						}
					}
				}()

				// 首先保存原始二进制数据，不管是否能解析
				if err := r.saveBinaryData(data[:n]); err != nil {
					if r.logger != nil {
						r.logger.Error("Failed to save raw binary data from %s: %v", client.address, err)
					} else {
						log.Printf("保存原始二进制数据失败 %s: %v", client.address, err)
					}
				}

				// 追加到缓冲区进行解析
				client.buffer = append(client.buffer, data[:n]...)

				// 处理完整的数据包 (WITS-A记录以\r\n结尾)
				r.processBuffer(client)
			}()
		}
	}
}

// processBuffer 处理缓冲区数据
func (r *WITSReceiver) processBuffer(client *WITSClient) {
	defer func() {
		if rec := recover(); rec != nil {
			if r.logger != nil {
				r.logger.Error("Panic recovered in processBuffer for client %s: %v", client.address, rec)
			} else {
				log.Printf("捕获到panic在processBuffer中，客户端: %s, 错误: %v", client.address, rec)
			}
		}
	}()

	for {
		// 查找记录结束标记
		idx := -1
		for i := 0; i < len(client.buffer)-1; i++ {
			if client.buffer[i] == '\r' && client.buffer[i+1] == '\n' {
				idx = i
				break
			}
		}

		if idx == -1 {
			break // 没有找到完整记录
		}

		// 提取完整记录（包括\r\n）
		record := client.buffer[:idx+2]
		client.buffer = client.buffer[idx+2:]

		// 解析并处理WITS数据（数据已经在handleClient中保存）
		go r.processWITSRecord(record, client.address)
	}
}

// saveBinaryData 保存原始二进制数据到文件
func (r *WITSReceiver) saveBinaryData(data []byte) error {
	defer func() {
		if rec := recover(); rec != nil {
			if r.logger != nil {
				r.logger.Error("Panic recovered in saveBinaryData: %v", rec)
			} else {
				log.Printf("捕获到panic在saveBinaryData中，错误: %v", rec)
			}
		}
	}()

	r.fileMutex.Lock()
	defer r.fileMutex.Unlock()

	// 检查是否需要创建新文件（按日期分文件）
	currentDate := time.Now().Format("20060102")
	if r.currentDate != currentDate || r.currentFile == nil {
		// 关闭旧文件
		if r.currentFile != nil {
			r.currentFile.Close()
		}

		// 创建新文件
		filename := fmt.Sprintf("wits-binary_%s.data", currentDate)
		filepath := filepath.Join(r.dataDir, filename)

		file, err := os.OpenFile(filepath, os.O_CREATE|os.O_APPEND|os.O_WRONLY, 0644)
		if err != nil {
			return fmt.Errorf("failed to create binary file: %v", err)
		}

		r.currentFile = file
		r.currentDate = currentDate
		if r.logger != nil {
			r.logger.Info("Created new binary data file: %s", filename)
		} else {
			log.Printf("创建新的二进制数据文件: %s", filename)
		}
	}

	// 写入数据（添加时间戳前缀）
	timestamp := time.Now().Format("2006-01-02 15:04:05.000")
	header := fmt.Sprintf("[%s %d]", timestamp, len(data))

	if _, err := r.currentFile.Write([]byte(header)); err != nil {
		return err
	}
	if _, err := r.currentFile.Write(data); err != nil {
		return err
	}

	return nil
}

// processWITSRecord 处理WITS记录
func (r *WITSReceiver) processWITSRecord(record []byte, clientAddr string) {
	defer func() {
		if rec := recover(); rec != nil {
			if r.logger != nil {
				r.logger.Error("Panic recovered in processWITSRecord from %s: %v", clientAddr, rec)
			} else {
				log.Printf("捕获到panic在processWITSRecord中，客户端: %s, 错误: %v", clientAddr, rec)
			}
		}
	}()

	// 使用自定义日志器（如果可用）或标准日志
	if r.logger != nil {
		r.logger.Info("收到WITS记录来自 %s: %d bytes", clientAddr, len(record))
	} else {
		log.Printf("收到WITS记录来自 %s: %d bytes", clientAddr, len(record))
	}

	// 尝试解析WITS数据
	witsData := r.parseWITSRecord(record)
	if witsData != nil {
		if r.logger != nil {
			r.logger.Debug("解析WITS数据: %+v", witsData)
		} else {
			log.Printf("解析WITS数据: %+v", witsData)
		}
	}

	// 调用数据处理回调函数（如果设置）
	if r.dataHandler != nil {
		r.dataHandler(record, clientAddr)
	}
}

// parseWITSRecord 解析WITS记录
func (r *WITSReceiver) parseWITSRecord(record []byte) map[string]interface{} {
	defer func() {
		if rec := recover(); rec != nil {
			if r.logger != nil {
				r.logger.Error("Panic recovered in parseWITSRecord: %v", rec)
			} else {
				log.Printf("捕获到panic在parseWITSRecord中，错误: %v", rec)
			}
		}
	}()

	// 简单的WITS解析逻辑，类似Python版本
	recordStr := string(record)
	recordStr = strings.TrimSpace(recordStr)

	if recordStr == "" {
		return nil
	}

	// 按逗号分割字段
	fields := strings.Split(recordStr, ",")
	if len(fields) < 3 {
		return nil
	}

	result := make(map[string]interface{})
	result["raw_data"] = recordStr
	result["field_count"] = len(fields)
	result["timestamp"] = time.Now().Format("2006-01-02 15:04:05")

	// 尝试解析一些基本字段
	if len(fields) > 0 {
		result["record_time"] = fields[0]
	}
	if len(fields) > 1 {
		result["record_type"] = fields[1]
	}
	if len(fields) > 2 {
		result["well_id"] = fields[2]
	}

	// 尝试解析数值字段（如果有）
	if len(fields) > 3 {
		if depth, err := strconv.ParseFloat(fields[3], 64); err == nil {
			result["hole_depth"] = depth
		}
	}
	if len(fields) > 4 {
		if bitDepth, err := strconv.ParseFloat(fields[4], 64); err == nil {
			result["bit_depth"] = bitDepth
		}
	}
	if len(fields) > 5 {
		if wob, err := strconv.ParseFloat(fields[5], 64); err == nil {
			result["wob"] = wob
		}
	}

	return result
}

// fileManager 文件管理协程
func (r *WITSReceiver) fileManager() {
	defer func() {
		if rec := recover(); rec != nil {
			if r.logger != nil {
				r.logger.Error("Panic recovered in fileManager: %v", rec)
			} else {
				log.Printf("捕获到panic在fileManager中，错误: %v", rec)
			}
		}
	}()

	ticker := time.NewTicker(1 * time.Hour) // 每小时检查一次
	defer ticker.Stop()

	for r.running {
		select {
		case <-ticker.C:
			// 在文件操作前添加panic保护
			func() {
				defer func() {
					if rec := recover(); rec != nil {
						if r.logger != nil {
							r.logger.Error("Panic recovered in fileManager ticker: %v", rec)
						} else {
							log.Printf("捕获到panic在fileManager ticker中，错误: %v", rec)
						}
					}
				}()

				// 检查是否需要切换文件
				r.fileMutex.Lock()
				currentDate := time.Now().Format("20060102")
				if r.currentDate != currentDate && r.currentFile != nil {
					r.currentFile.Close()
					r.currentFile = nil
					r.currentDate = ""
				}
				r.fileMutex.Unlock()
			}()
		}
	}
}

// GetStats 获取接收统计信息
func (r *WITSReceiver) GetStats() map[string]interface{} {
	r.mutex.RLock()
	clientCount := len(r.clients)
	r.mutex.RUnlock()

	return map[string]interface{}{
		"client_count": clientCount,
		"is_running":   r.running,
		"data_dir":     r.dataDir,
		"current_date": r.currentDate,
	}
}
